package com.xu.cloud.common.util;

import com.xu.cloud.common.exception.ErrorCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.NonNull;
import org.springframework.util.AntPathMatcher;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 静态资源
 *
 * @author xuguan
 * @since 2023/7/15
 */
@Slf4j
public class ResourceUtil {
    public static final Set<String> staticResourceTypes = Stream.of(
                    ".html", ".css", ".js", ".png", ".jpg", ".jpeg", ".svg", ".gif", ".ico",
                    ".otf", ".eot", ".ttf", ".woff", ".woff2", ".txt", ".zip", ".gzip", ".xz", ".tar",
                    ".gz", ".bz2", ".tgz", ".jar", ".war", "map")
            .collect(Collectors.toSet());

    public static final Set<String> staticUrlPatterns = Stream.of(
                    "/resources/**", "/static/**", "/html/**", "/css/**", "/js/**", "/image/**", "/img/**",
                    "/**/*.js", "/**/*.css", "/**/*.html", "/**/*.ico",
                    "/**/swagger/**", "/**/webjars/**", "/**/swagger-ui.html", "/**/swagger-resources/**", "/v2/api-docs/**", "/v3/api-docs/**",
                    "/druid/**",
                    "/actuator/**", "/error")
            .collect(Collectors.toSet());

    public static final Set<String> openUrlPatterns = Stream.of(
                    "/open/**", "/login/**", "/register/**",
                    "/api/open/**", "/api/login/**", "/api/register/**")
            .collect(Collectors.toSet());


    public static boolean isStatic(@NonNull String uriStr) {
        return isStaticResource(uriStr) || isStaticUrl(uriStr);
    }

    public static boolean isStaticResource(@NonNull String uri) {
        if (uri.contains(".")) {
            String staticResourceType = uri.substring(uri.lastIndexOf("."));
            return staticResourceTypes.contains(staticResourceType);
        }
        return false;
    }

    public static boolean isStaticUrl(@NonNull String uriStr) {
        return antPathMatch(staticUrlPatterns, getUri(uriStr).getPath());
    }

    public static boolean isOpenUrl(@NonNull String uriStr) {
        return antPathMatch(openUrlPatterns, getUri(uriStr).getPath());
    }

    public static List<String> staticResourceTypes() {
        return new ArrayList<>(staticResourceTypes);
    }

    public static List<String> staticUrlPatterns() {
        return new ArrayList<>(staticUrlPatterns);
    }

    public static List<String> openUrlPatterns() {
        return new ArrayList<>(openUrlPatterns);
    }

    private static URI getUri(String uriStr) {
        URI uri;
        try {
            uri = new URI(uriStr);
        } catch (URISyntaxException e) {
            log.error("Http Url地址: [{}], 格式不合法", uriStr);
            throw ExceptionUtil.wrapXuCloudException(ErrorCodeEnum.ERR_ILLEGAL_PARAM, e);
        }
        return uri;
    }

    private static boolean antPathMatch(Collection<String> patterns, String uriPath) {
        final AntPathMatcher apm = new AntPathMatcher();
        for (String pattern : patterns) {
            if (apm.match(pattern, uriPath)) {
                return true;
            }
        }
        return false;
    }
}
